<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>渲染PBF矢量瓦片图层 - 带属性查询</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        .control-panel {
            position: absolute;
            top: 10px;
            left: 10px;
            z-index: 999;
            background: white;
            padding: 15px;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            max-width: 350px;
        }
        .control-panel h3 {
            margin-top: 0;
            color: #333;
        }
        .form-group {
            margin-bottom: 10px;
        }
        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        .form-group input, .form-group select {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .form-group button {
            background: #1e88e5;
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
            margin-bottom: 5px;
        }
        .form-group button:hover {
            background: #1976d2;
        }
        .info-panel {
            position: absolute;
            bottom: 10px;
            left: 10px;
            z-index: 999;
            background: white;
            padding: 10px;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            font-size: 12px;
        }
        .legend {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 999;
            background: white;
            padding: 15px;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            max-width: 200px;
        }
        .legend h4 {
            margin-top: 0;
        }
        .legend-item {
            display: flex;
            align-items: center;
            margin-bottom: 5px;
        }
        .legend-color {
            width: 20px;
            height: 20px;
            margin-right: 10px;
            border: 1px solid #ccc;
        }
        .mapboxgl-popup-content {
            max-height: 300px;
            overflow-y: auto;
        }
        .popup-title {
            font-weight: bold;
            margin-bottom: 10px;
            padding-bottom: 5px;
            border-bottom: 1px solid #eee;
        }
        .popup-attribute {
            margin-bottom: 5px;
        }
        .popup-attribute .attr-name {
            font-weight: bold;
            display: inline-block;
            width: 120px;
        }
        .loading-indicator {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 4px;
            z-index: 1000;
            display: none;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    
    <div class="control-panel">
        <h3>PBF图层设置</h3>
        <div class="form-group">
            <label for="pbf-url">PBF服务地址:</label>
            <input type="text" id="pbf-url" value="http://8.134.103.174:8081/pbf/guandongpbf/{z}/{x}/{y}.pbf">
        </div>
        <div class="form-group">
            <label for="min-zoom">最小缩放级别:</label>
            <input type="number" id="min-zoom" value="4" min="0" max="20">
        </div>
        <div class="form-group">
            <label for="max-zoom">最大缩放级别:</label>
            <input type="number" id="max-zoom" value="14" min="0" max="20">
        </div>
        <div class="form-group">
            <button onclick="updateLayer()">更新图层</button>
            <button onclick="clearSelection()">清除选中</button>
        </div>
    </div>
    
    <div class="legend">
        <h4>图例</h4>
        <div class="legend-item">
            <div class="legend-color" style="background-color: rgba(255, 0, 0, 0.5);"></div>
            <span>点要素</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: rgba(0, 0, 255, 0.5);"></div>
            <span>线要素</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: rgba(0, 255, 0, 0.5);"></div>
            <span>面要素</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background-color: rgba(255, 255, 0, 0.7); border: 2px solid #ff0000;"></div>
            <span>选中要素</span>
        </div>
    </div>
    
    <div class="info-panel">
        <div>缩放级别: <span id="zoom-level">-</span></div>
        <div>中心点: <span id="center-coord">-</span></div>
        <div>图层状态: <span id="layer-status">未加载</span></div>
        <div>点击要素: <span id="click-info">无</span></div>
    </div>
    
    <div id="loading" class="loading-indicator">正在加载数据...</div>

    <!-- 引入Mapbox GL JS -->
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script>
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet">
    
    <script>
        // 初始化Mapbox GL JS（无需access token）
        mapboxgl.accessToken = 'none';
        
        let map;
        let vectorLayerId = 'pbf-layer';
        let popup = new mapboxgl.Popup({
            closeButton: true,
            closeOnClick: false
        });
        let selectedFeatureProperties = null;
        
        // 初始化地图
        function initMap() {
            map = new mapboxgl.Map({
                container: 'map',
                style: {
                    "version": 8,
                    "sources": {
                        "gaode-base": {
                            "type": "raster",
                            "tiles": [
                                "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
                            ],
                            "tileSize": 256
                        }
                    },
                    "layers": [
                        {
                            "id": "gaode-base-layer",
                            "type": "raster",
                            "source": "gaode-base",
                            "minzoom": 0,
                            "maxzoom": 22
                        }
                    ]
                },
                center: [113.2644, 23.1291], // 广东省广州市附近
                zoom: 9,
                hash: true
            });
            
            // 添加导航控件
            map.addControl(new mapboxgl.NavigationControl(), 'top-right');
            
            // 监听地图事件
            map.on('load', function() {
                addPbfLayer();
                updateInfo();
                setupClickHandler();
            });
            
            map.on('moveend', updateInfo);
            map.on('zoomend', updateInfo);
        }
        
        // 添加PBF矢量图层
        function addPbfLayer() {
            showLoading(true);
            
            // 移除已存在的图层
            removeExistingLayers();
            
            const pbfUrl = document.getElementById('pbf-url').value;
            const minZoom = parseInt(document.getElementById('min-zoom').value);
            const maxZoom = parseInt(document.getElementById('max-zoom').value);
            
            // 添加矢量瓦片源
            map.addSource('pbf-source', {
                type: 'vector',
                tiles: [pbfUrl],
                minzoom: minZoom,
                maxzoom: maxZoom
            });
            
            // 添加矢量图层（面要素）
            map.addLayer({
                'id': vectorLayerId + '-fill',
                'type': 'fill',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'fill-color': '#00ff00',
                    'fill-opacity': 0.5
                },
                'filter': ['==', '$type', 'Polygon']
            });
            
            // 添加面要素边框
            map.addLayer({
                'id': vectorLayerId + '-fill-outline',
                'type': 'line',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'line-color': '#006600',
                    'line-width': 1
                },
                'filter': ['==', '$type', 'Polygon']
            });
            
            // 添加矢量图层（线要素）
            map.addLayer({
                'id': vectorLayerId + '-line',
                'type': 'line',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'line-color': '#0000ff',
                    'line-width': 2,
                    'line-opacity': 0.7
                },
                'filter': ['==', '$type', 'LineString']
            });
            
            // 添加矢量图层（点要素）
            map.addLayer({
                'id': vectorLayerId + '-point',
                'type': 'circle',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'circle-radius': 5,
                    'circle-color': '#ff0000',
                    'circle-opacity': 0.7,
                    'circle-stroke-width': 1,
                    'circle-stroke-color': '#ffffff'
                },
                'filter': ['==', '$type', 'Point']
            });
            
            // 添加选中状态图层（面）
            map.addLayer({
                'id': vectorLayerId + '-fill-selected',
                'type': 'fill',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'fill-color': '#ffff00',
                    'fill-opacity': 0.1
                },
                'filter': ['==', 'adcode', '']
            });
            
            // 添加选中状态图层边框（面）
            map.addLayer({
                'id': vectorLayerId + '-fill-outline-selected',
                'type': 'line',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'line-color': '#ff0000',
                    'line-width': 1
                },
                'filter': ['==', 'adcode', '']
            });
            
            // 添加选中状态图层（线）
            map.addLayer({
                'id': vectorLayerId + '-line-selected',
                'type': 'line',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'line-color': '#ff0000',
                    'line-width': 1,
                    'line-opacity': 0.8
                },
                'filter': ['==', 'adcode', '']
            });
            
            //添加选中状态图层（点）
            map.addLayer({
                'id': vectorLayerId + '-point-selected',
                'type': 'circle',
                'source': 'pbf-source',
                'source-layer': 'guandong',
                'paint': {
                    'circle-radius': 1,
                    'circle-color': '#ffff00',
                    'circle-opacity': 0.8,
                    'circle-stroke-width': 2,
                    'circle-stroke-color': '#ff0000'
                },
                'filter': ['==', 'adcode', '']
            });
            
            document.getElementById('layer-status').textContent = '已加载';
            showLoading(false);
        }
        
        // 移除已存在的图层
        function removeExistingLayers() {
            const layers = [
                vectorLayerId + '-point',
                vectorLayerId + '-line',
                vectorLayerId + '-fill',
                vectorLayerId + '-fill-outline',
                vectorLayerId + '-point-selected',
                vectorLayerId + '-line-selected',
                vectorLayerId + '-fill-selected',
                vectorLayerId + '-fill-outline-selected'
            ];
            
            layers.forEach(layerId => {
                if (map.getLayer(layerId)) {
                    map.removeLayer(layerId);
                }
            });
            
            if (map.getSource('pbf-source')) {
                map.removeSource('pbf-source');
            }
        }
        
        // 设置点击事件处理
        function setupClickHandler() {
            // 为每个图层添加点击事件
            ['fill', 'line', 'point'].forEach(layerType => {
                map.on('click', vectorLayerId + '-' + layerType, function(e) {
                    showFeatureInfo(e);
                });
                
                // 鼠标悬停效果
                map.on('mouseenter', vectorLayerId + '-' + layerType, function() {
                    map.getCanvas().style.cursor = 'pointer';
                });
                
                map.on('mouseleave', vectorLayerId + '-' + layerType, function() {
                    map.getCanvas().style.cursor = '';
                });
            });
        }
        
        // 显示要素信息
        function showFeatureInfo(e) {
            const feature = e.features[0];
            if (!feature) return;
            
            // 更新选中状态
            updateSelectedFeature(feature.properties);
            
            // 构建属性信息
            let content = '<div class="popup-title">要素属性信息</div>';
            
            // 显示几何类型
            content += `<div class="popup-attribute"><span class="attr-name">几何类型:</span> ${feature.geometry.type}</div>`;
            
            // 显示属性信息
            for (let prop in feature.properties) {
                if (feature.properties.hasOwnProperty(prop)) {
                    content += `<div class="popup-attribute"><span class="attr-name">${prop}:</span> ${feature.properties[prop]}</div>`;
                }
            }
            
            // 显示坐标信息（对于点要素）
            if (feature.geometry.type === 'Point' && feature.geometry.coordinates) {
                const coords = feature.geometry.coordinates;
                content += `<div class="popup-attribute"><span class="attr-name">坐标:</span> ${coords[0].toFixed(6)}, ${coords[1].toFixed(6)}</div>`;
            }
            
            // 在地图上显示弹窗
            popup.setLngLat(e.lngLat)
                .setHTML(content)
                .addTo(map);
            
            // 更新信息面板
            const name = feature.properties.name || feature.properties.adcode || '未知';
            document.getElementById('click-info').textContent = name;
        }
        
        // 更新选中要素的高亮显示
        function updateSelectedFeature(properties) {
            if (!properties) return;
            
            selectedFeatureProperties = properties;
            
            // 使用adcode或其他唯一标识符来高亮选中要素
            let identifierValue = '';
            let identifierKey = 'adcode'; // 默认使用adcode作为标识符
            
            // 尝试获取唯一标识符
            if (properties.adcode) {
                identifierValue = properties.adcode;
            } else if (properties.id) {
                identifierValue = properties.id;
                identifierKey = 'id';
            } else if (properties.name) {
                identifierValue = properties.name;
                identifierKey = 'name';
            }
            
            // 更新各图层的过滤器以高亮选中要素
            if (identifierValue) {
                map.setFilter(vectorLayerId + '-fill-selected', ['==', identifierKey, identifierValue]);
                map.setFilter(vectorLayerId + '-fill-outline-selected', ['==', identifierKey, identifierValue]);
                map.setFilter(vectorLayerId + '-line-selected', ['==', identifierKey, identifierValue]);
                map.setFilter(vectorLayerId + '-point-selected', ['==', identifierKey, identifierValue]);
            }
        }
        
        // 清除选中状态
        function clearSelection() {
            popup.remove();
            selectedFeatureProperties = null;
            
            // 清除高亮显示
            if (map.getLayer(vectorLayerId + '-fill-selected')) {
                map.setFilter(vectorLayerId + '-fill-selected', ['==', 'adcode', '']);
                map.setFilter(vectorLayerId + '-fill-outline-selected', ['==', 'adcode', '']);
                map.setFilter(vectorLayerId + '-line-selected', ['==', 'adcode', '']);
                map.setFilter(vectorLayerId + '-point-selected', ['==', 'adcode', '']);
            }
            
            document.getElementById('click-info').textContent = '无';
        }
        
        // 更新图层
        function updateLayer() {
            try {
                addPbfLayer();
                document.getElementById('layer-status').textContent = '更新成功';
                clearSelection(); // 更新图层后清除选中状态
            } catch (error) {
                document.getElementById('layer-status').textContent = '更新失败: ' + error.message;
            }
        }
        
        // 更新信息显示
        function updateInfo() {
            if (map) {
                document.getElementById('zoom-level').textContent = map.getZoom().toFixed(2);
                const center = map.getCenter();
                document.getElementById('center-coord').textContent = 
                    `${center.lng.toFixed(6)}, ${center.lat.toFixed(6)}`;
            }
        }
        
        // 显示/隐藏加载指示器
        function showLoading(show) {
            document.getElementById('loading').style.display = show ? 'block' : 'none';
        }
        
        // 页面加载完成后初始化地图
        window.onload = function() {
            initMap();
        };
    </script>
</body>
</html>
